#include "HTTPRequest.h"
#include "StringUtil.h"
#include "ISocket.h"
SK
HTTPRequest::HTTPRequest ()
: valid (false), contentLength(-1)
{

}

HTTPRequest::HTTPRequest (const HTTPRequest& other)
{

}

HTTPRequest::HTTPRequest (const String& requestStr)
{
	this->parse (requestStr);
}

bool HTTPRequest::extractFileInfo (const String& fle)
{
	//filter out dodget URL'ss eg ../../
	if (fle.find("..") != String::npos)
	{
		return false;
	}
	else if (fle.find("~") != String::npos)
	{
		return false;
	}

	if (fle == "/")
		this->file = "\\index.htm";
	else
	{
		this->file = fle;
	}

	//get the file type
	int extLoc = file.find ('.');

	if (extLoc == String::npos)
		this->fileType = HTTP_FILE_TYPE_UNKNOWN;
	else
	{
		String ext = StringUtil::toLowerCase(file.substr (extLoc +1));

		if (ext == "htm")
		{
			this->fileType = HTTP_FILE_TYPE_HTML;
			this->fileMode = HTTP_FILE_MODE_TEXT;
			fileMIME = "text/html";
		}
		else if (ext == "html")
		{
			this->fileType = HTTP_FILE_TYPE_HTML;
			this->fileMode = HTTP_FILE_MODE_TEXT;
			fileMIME = "text/html";
		}
		else if (ext == "bmp")
		{
			this->fileType = HTTP_FILE_TYPE_BMP;
			this->fileMode = HTTP_FILE_MODE_BINARY;
			fileMIME = "image/bmp";
		}
		else if (ext == "jpg")
		{
			this->fileType = HTTP_FILE_TYPE_JPG;
			this->fileMode = HTTP_FILE_MODE_BINARY;
			fileMIME = "image/jpeg";
		}
		else if (ext == "jpeg")
		{
			this->fileType = HTTP_FILE_TYPE_JPG;
			this->fileMode = HTTP_FILE_MODE_BINARY;
			fileMIME = "image/jpeg";
		}
		else if (ext == "png")
		{
			this->fileType = HTTP_FILE_TYPE_PNG;
			this->fileMode = HTTP_FILE_MODE_BINARY;
			fileMIME = "image/png";
		}
		else if (ext == "xml")
		{
			this->fileType = HTTP_FILE_TYPE_XML;
			this->fileMode = HTTP_FILE_MODE_TEXT;
		}
		else if (ext == "js")
		{
			this->fileType = HTTP_FILE_TYPE_JS;
			this->fileMode = HTTP_FILE_MODE_TEXT;
			fileMIME = "text/javascript";
		}
		else if (ext == "css")
		{
			this->fileType = HTTP_FILE_TYPE_CSS;
			this->fileMode = HTTP_FILE_MODE_TEXT;
			fileMIME = "text/css";
		}
		else if (ext == "jarv")
		{
			this->fileType = HTTP_FILE_TYPE_JARVCMD;
			this->fileMode = HTTP_FILE_MODE_BINARY;
			fileMIME = "text/json";
		}
		else
		{
			this->fileType = HTTP_FILE_TYPE_UNKNOWN;
			this->fileMode = HTTP_FILE_MODE_BINARY;
		}

	}

	return true;
}

void HTTPRequest::parse (const String& requestStr)
{
	StringArray lines = StringUtil::split (requestStr, L'\n');
	if (lines.size() == 0)
		return;

	StringArray requestLine = StringUtil::split (lines [0], L' ');

	if (requestLine.size () != 3)
		return;	//error

	if (requestLine[0] == "GET")
		this->method = HTTP_GET;
	else if (requestLine[0] == "POST")
		this->method = HTTP_POST;
	else
		this->method = HTTP_UNKNOWN;

	if (!extractFileInfo (requestLine [1]))
	{
		valid = false;
		return;
	}
	

	//Parse the rest of the headers
	for (int i=1; i<lines.size();i++)
	{
		int colLoc = lines [i].find (L':');

		if (colLoc == String::npos)
			continue;	//line is malformed

		String header = StringUtil::toLowerCase (lines [i].substr(0, colLoc));
		String val = StringUtil::toLowerCase (lines [i].substr (lines[i].find_first_not_of(' ', colLoc+1)));
		
		if (header == "host")
			this->host = val;
		else if (header == "connection")
		{
			if (val == "close")
				this->conKeepAlive = false;
			else if (val == "keep-alive")
				this->conKeepAlive = true;
		}
		else if (header == "user-agent")
			this->userAgent = val;
		else if (header == "accept-encoding")
			this->acceptedEncodings = StringUtil::split (val,',');
		else if (header == "content-length")
			this->contentLength = StringUtil::parseInt (val);
		else
			otherHeaders.insert (std::pair <String, String>(header, val));
	}


}

bool HTTPRequest::isValid (void)
{
	return valid;
}

EK